﻿using Futajma.MigrationStudio.DataDefinition;
using LLTreeManagementApplication.Data;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;

namespace LLTreeManagementApplication.Configuration
{
    [Flags]
    enum State
    {
        False = 0,
        True = 1,
        OnlyIfGovernanceIssue = 2,
    }

    public class GovernanceHandler
    {
        public GovernanceData GovernanceData { get; set; }


        public GovernanceHandler()
        {
            GovernanceData = new GovernanceData(true);
        }

        public void ImportDefinition(string filename)
        {
            //XmlReaderSettings settings = new XmlReaderSettings();
            //settings.Encoding = new UnicodeEncoding(false, false); // no BOM in a .NET string
            //settings.Indent = true;
            ////settings.OmitXmlDeclaration = true;

            XmlSerializer serializer = new XmlSerializer(typeof(GovernanceData));

            using (XmlReader reader = XmlReader.Create(filename))
            {
                GovernanceData = (GovernanceData)serializer.Deserialize(reader);
            }

        }

        public void SaveSettings(string filename)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = new UnicodeEncoding(false, false); // no BOM in a .NET string
            settings.Indent = true;
            //settings.OmitXmlDeclaration = true;

            XmlSerializer serializer = new XmlSerializer(typeof(GovernanceData));

            using (XmlWriter writer = XmlWriter.Create(filename, settings))
            {
                serializer.Serialize(writer, GovernanceData);
            }
        }
    }

    /*
    public class GovernanceData
    {
        #region Content Reorganisation Rules
        public bool AllowExcludeItems { get; set; }
        public bool AllowExcludeItemsOnlyByGovernanceIssue { get; set; }

        public bool AllowExcludeFolders { get; set; }
        public bool AllowExcludeFoldersOnlyByGovernanceIssue { get; set; }

        public bool AllowExcludeLibraries { get; set; }
        public bool AllowExcludeLibrariesOnlyByGovernanceIssue { get; set; }

        public bool AllowExcludeSites { get; set; }
        public bool AllowExcludeSitesOnlyByGovernanceIssue { get; set; }

        public bool AllowExcludeSiteCollections { get; set; }
        public bool AllowExcludeSiteCollectionsOnlyByGovernanceIssue { get; set; }

        public bool AllowMoveItems { get; set; }
        public bool AllowMoveItemsOnlyByGovernanceIssue { get; set; }

        public bool AllowMoveFolders { get; set; }
        public bool AllowMoveFoldersOnlyByGovernanceIssue { get; set; }

        public bool AllowMoveLibraries { get; set; }
        public bool AllowMoveLibrariesOnlyByGovernanceIssue { get; set; }

        public bool AllowMoveSites { get; set; }
        public bool AllowMoveSitesOnlyByGovernanceIssue { get; set; }

        public bool AllowMoveSiteCollections { get; set; }
        public bool AllowMoveSiteCollectionsOnlyByGovernanceIssue { get; set; }
        #endregion

        #region GovernanceLimitations
        public int ListItemThreshold { get; set; }

        public int FileSizeLimit { get; set; }

        public long SiteCollectionSizeLimit { get; set; }

        public int PathLenghtLimit { get; set; }

        public int DefaultPlattformUrlPathLength { get; set; }

        public bool ExcludeSiteCollectionNamesInPathCalulation {get;set;}
        #endregion

        #region Constructor
        public GovernanceData()
        {
            #region Preset Content Reorganisation values
            AllowExcludeItems = false;
            AllowExcludeItemsOnlyByGovernanceIssue = true;
            AllowExcludeFolders = false;
            AllowExcludeFoldersOnlyByGovernanceIssue = true;
            AllowExcludeLibraries = true;
            AllowExcludeLibrariesOnlyByGovernanceIssue = true;
            AllowExcludeSites = true;
            AllowExcludeSitesOnlyByGovernanceIssue = true;
            AllowExcludeSiteCollections = true;
            AllowExcludeSiteCollectionsOnlyByGovernanceIssue = true;

            AllowMoveItems = false;
            AllowMoveItemsOnlyByGovernanceIssue = true;
            AllowMoveFolders = false;
            AllowMoveFoldersOnlyByGovernanceIssue = true;
            AllowMoveLibraries = true;
            AllowMoveLibrariesOnlyByGovernanceIssue = true;
            AllowMoveSites = true;
            AllowMoveSitesOnlyByGovernanceIssue = true;
            AllowMoveSiteCollections = true;
            AllowMoveSiteCollectionsOnlyByGovernanceIssue = true;
            #endregion

            #region Preset Governance Limitations
            ListItemThreshold = 5000;
            FileSizeLimit = 262144000; //(250MB)
            SiteCollectionSizeLimit = 53687091200; //(50GB)
            DefaultPlattformUrlPathLength = 50;
            PathLenghtLimit = 255;
            ExcludeSiteCollectionNamesInPathCalulation = true;
            #endregion

        }
        #endregion

        #region Methods

        public bool IsExcludeCheckBoxEnabled(DataNode node)
        {
            if (node.ExcludeableFromMigration)
            {
                return true;
            }

            bool ret = false;
            switch (node.SharePointType)
            {
                case SharePointType.Application:

                    break;
                case SharePointType.SiteCollection:
                    ret = AllowExcludeSiteCollections || AllowExcludeSiteCollectionsOnlyByGovernanceIssue && node.GovernanceViolation;
                    break;
                case SharePointType.Site:
                    ret = AllowExcludeSites || AllowExcludeSitesOnlyByGovernanceIssue && node.GovernanceViolation;
                    break;
                case SharePointType.DocLibrary:
                    ret = AllowExcludeLibraries || AllowExcludeLibrariesOnlyByGovernanceIssue && node.GovernanceViolation;
                    break;
                case SharePointType.Folder:
                    ret = AllowExcludeFolders || AllowExcludeFoldersOnlyByGovernanceIssue && node.GovernanceViolation;
                    break;
                case SharePointType.Item:
                case SharePointType.Document:
                    ret = AllowExcludeItems || AllowExcludeItemsOnlyByGovernanceIssue && node.GovernanceViolation;
                    break;
            }
            return ret;
        }

        public bool IsNodeMovable(DataNode node)
        {
            bool ret = false;
            switch (node.SharePointType)
            {
                case SharePointType.Application:
                    ret = false;
                    break;
                case SharePointType.SiteCollection:
                    ret = AllowMoveSiteCollections || AllowMoveSiteCollectionsOnlyByGovernanceIssue && node.GovernanceViolation;
                    break;
                case SharePointType.Site:
                    ret = AllowMoveSites || AllowMoveSitesOnlyByGovernanceIssue && node.GovernanceViolation;
                    break;
                case SharePointType.DocLibrary:
                    ret = AllowMoveLibraries || AllowMoveLibrariesOnlyByGovernanceIssue && node.GovernanceViolation;
                    break;
                case SharePointType.Folder:
                    ret = AllowMoveFolders || AllowMoveFoldersOnlyByGovernanceIssue && node.GovernanceViolation;
                    break;
                case SharePointType.Item:
                case SharePointType.Document:
                    ret = AllowMoveItems || AllowMoveItemsOnlyByGovernanceIssue && node.GovernanceViolation;
                    break;
            }
            return ret;
        }

        public void ResetGovernanceCheck(TreeView treeView)
        {
            foreach (TreeNode node in treeView.Nodes)
            {
                //RecoloringTree(node);
                ResetViolationChecks(node);
            }
        }

        public void CheckGovernanceVoilations(TreeView treeView)
        {
            foreach (TreeNode node in treeView.Nodes)
            {
                ResetViolationChecks(node);
                CalculateItemThresholdViolation(node);
                CalculateItemSizeExceededViolation(node);
                CalculatePathLengthExceededViolation(node, DefaultPlattformUrlPathLength);
                SetViolationStates(node);
            }
        }

        #endregion

        #region Private Methods

        private int CalculateItemThresholdViolation(TreeNode node)
        {
            int value = 0;

            DataNode currDataNode = node.Tag as DataNode;

            if (currDataNode.SharePointType == SharePointType.DocLibrary)
            {
                foreach (TreeNode child in node.Nodes)
                {
                    var data = child.Tag as DataNode;

                    if ((data.SharePointType == SharePointType.Document ||
                        data.SharePointType == SharePointType.Item) && !currDataNode.ExcludeFromMigration)
                    {
                        value++;
                    }
                }

                if (value > ListItemThreshold)
                {
                    currDataNode.ItemThresholdExceededCount = 1;
                    value = 1;
                    currDataNode.GovernanceViolation = true;
                    currDataNode.ViolationType |= ViolationType.ItemThresholdExceeded;
                    //if (currDataNode.GovernanceViolation)
                    //{
                    currDataNode.ExcludeableFromMigration = true;
                    //}

                    //if (coloring)
                    //{
                    //    if (currDataNode.Deletable == false)
                    //    {
                    //        node.ForeColor = Color.Red;
                    //    }
                    //    else
                    //    {
                    //        node.ForeColor = Color.DarkRed;
                    //    }
                    //}
                }
                else
                {
                    value = 0;
                }
            }
            else
            {
                foreach (TreeNode child in node.Nodes)
                {
                    value += CalculateItemThresholdViolation(child);
                }
                currDataNode.ItemThresholdExceededCount = value;

            }
            return value;
        }

        private long CalculateItemSizeExceededViolation(TreeNode node)
        {
            long value = 0;
            #region Recursive tree iteration
            foreach (TreeNode child in node.Nodes)
            {
                value += CalculateItemSizeExceededViolation(child);
            }

            DataNode currDataNode = node.Tag as DataNode;

            if (currDataNode != null)
            {
                if (currDataNode.FileSize > FileSizeLimit && !currDataNode.ExcludeFromMigration)
                {
                    value++;
                    currDataNode.GovernanceViolation = true;
                    currDataNode.ViolationType |= ViolationType.ItemSizeExceeded;

                    if (currDataNode.GovernanceViolation)
                    {
                        currDataNode.ExcludeableFromMigration = true;
                    }
                }
                currDataNode.ItemSizeExceededCount = (int)value;
            }

            return value;
            #endregion
        }

        private bool CalculatePathLengthExceededViolation(TreeNode node, int parentPathLength)
        {
            bool value = false;

            #region Recursive tree iteration

            DataNode currDataNode = node.Tag as DataNode;

            if (currDataNode != null)
            {
                if (!(ExcludeSiteCollectionNamesInPathCalulation && (currDataNode.SharePointType == SharePointType.Application || currDataNode.SharePointType == SharePointType.SiteCollection)))
                {
                    parentPathLength += currDataNode.Title.Length;

                    currDataNode.PathLength = parentPathLength;

                    if (parentPathLength > PathLenghtLimit && !currDataNode.ExcludeFromMigration)
                    {
                        value = true;
                        currDataNode.GovernanceViolation = true;
                        currDataNode.ViolationType |= ViolationType.PathLengthExceeded;

                        if (currDataNode.GovernanceViolation)
                        {
                            currDataNode.ExcludeableFromMigration = true;
                        }
                    }
                }
            }

            foreach (TreeNode child in node.Nodes)
            {
                if (CalculatePathLengthExceededViolation(child, parentPathLength))
                {
                    value = true;
                }
            }
            return value;
            #endregion
        }

        private void ResetViolationChecks(TreeNode node)
        {
            foreach (TreeNode child in node.Nodes)
            {
                ResetViolationChecks(child);
            }

            DataNode data = node.Tag as DataNode;

            data.GovernanceViolation = false;
            data.GovernanceViolationCollected = 0;
            data.ItemSizeExceededCount = 0;
            data.ItemThresholdExceededCount = 0;
            data.SharePointStructureViolation = false;
            data.SharePointStructureViolationCollected = 0;
            data.ViolationType = ViolationType.NoViolation;
            data.PathLength = 0;

            if (data == null || data.Deletable == false)
            {
                node.ForeColor = SystemColors.ControlText;
            }
            else
            {
                node.ForeColor = Color.DarkOrange;
            }
        }

        private int SetViolationStates(TreeNode node)
        {
            int value = 0;
            DataNode data = node.Tag as DataNode;

            foreach (TreeNode child in node.Nodes)
            {
                data.GovernanceViolationCollected += SetViolationStates(child);
            }
            value = data.GovernanceViolationCollected;

            //  if a violation occurs in the node self
            //data.GovernanceViolation = data.ItemSizeExceededCount > 0 || data.ItemThresholdExceededCount > 0;

            if (data.GovernanceViolation)
            {
                value++;
            }

            if (data.GovernanceViolation || value > 0)
            {
                //if (data == null || data.Deletable == false)
                //{
                node.ForeColor = Color.Red;
                //}
                //else
                //{
                //    node.ForeColor = Color.DarkRed;
                //}
            }

            return value;
        }

        #endregion
    }
    */
}
